home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 April: Mac OS SDK / Dev.CD Apr 99 SDK1.toast / Development Kits / Zoomed Video Driver v1.0 SDK / Tools / PC Card DispNameReg / Src / TwistDownList.h < prev   
Encoding:
C/C++ Source or Header  |  1997-06-02  |  17.9 KB  |  467 lines  |  [TEXT/CWIE]

  1. /*                                    TwistDownList.h                                */
  2. /*
  3.  * List In A List Sample
  4.  * TwistDownList.h
  5.  * Copyright © 1993-94 Apple Computer Inc. All rights reserved.
  6.  * Edit History
  7.  * 94.01.03 MM    Original release for the develop article.
  8.  * 94.10.16 MM    Use pascal calling conventions (reader suggestion). Reserved flag
  9.  *                bits for application programs; added a sort function; changed the
  10.  *                user-specified drawing function so that the TwistDownRecord is
  11.  *                passed (as a pointer to a locked handle) so that the drawing
  12.  *                function can access the flag bits. Added horizontal scrollbar
  13.  *                support. Added "sibling-set" functions to simplify normal list
  14.  *                operation. Updated to Universal Headers (ETO 15).
  15.  * 94.11.26 MM    Updated for headers "Universal Interfaces 2.0a3c1" -- these
  16.  *                are incompatible with ETO 15.
  17.  *
  18.  * Note that "list" is ambiguous, referring either to a List Manager list or to
  19.  * a "Lisp-like" list. In the following documentation, "cell" will always refer
  20.  * to a List Manager list cell, while "element" will always refer to a Lisp
  21.  * cell. Note that elements are not always displayed by the List Manager.
  22.  */
  23. #ifndef _TwistDownList_
  24. #define _TwistDownList_
  25.  
  26. #ifndef REZ
  27.  
  28. #include <Events.h>
  29. #include <Lists.h>
  30. #include <Printing.h>
  31.  
  32. #ifndef TRUE
  33. #define TRUE                1
  34. #define FALSE                0
  35. #endif
  36. #ifndef NULL
  37. #define NULL                0
  38. #endif
  39. /*
  40.  * This is the resource ID of the callback stub that must be defined in the
  41.  * application's resource fork. See the example in ListInAList.r.
  42.  */
  43. #define LDEF_Stub            1024
  44. /*
  45.  * TwistDownClickState is the value returned by DoTwistDownClick.
  46.  */
  47. typedef enum {
  48.     kTwistDownNotInList = 0,            /* The click was not in this list        */
  49.     kTwistDownNoClick,                    /* User changed mind                    */
  50.     kTwistDownButtonClick,                /* Clicked on twist-down button            */
  51.     kTwistDownClick,                    /* Single-click on list datum            */
  52.     kTwistDownDoubleClick                /* Double-click on list datum            */
  53. } TwistDownClickState;
  54.  
  55. /*
  56.  * This is the information needed to manage the twist-down display list. It is,
  57.  * essentially, a classical Lisp list with recursively-defined sublists. Each
  58.  * element contains enough information to display one component. This list is
  59.  * stored in a handle stored in the list's private data handle. The ListManager
  60.  * list cells contain TwistDownHdl pointers to the visible elements.
  61.  * A value of NULL in nextElement indicates the end of a list or sublist.
  62.  * A value of NULL in subElement means that there are no sub-elements (this
  63.  * is a leaf). Note that the Macintosh memory manager handles garbage collection.
  64.  *
  65.  * The flag bits have the following meanings:
  66.  *    kHasTwistDown        This list element is a sub-list (it may be empty).
  67.  *                        Draw the twist-down button (even if subElement is NULL).
  68.  *    kShowSubList        This list element is has a sub-list and the user wants
  69.  *                        to see the contents of the sub-list, too.
  70.  *    kOldShowSubList        This would be used to save the state of the kShowSubList
  71.  *                        flag if it needs to be changed temporarily (to show
  72.  *                        the entire hierarchy, for example).
  73.  * The following flags are only needed by the mouse-click handler.
  74.  *    kDrawButtonFilled    This is used by the mouse-click handler to signal
  75.  *                        "mouse-down in button." The LDEF fills the button area.
  76.  *    kOnlyRedrawButton    This is used by the mouse-click handler to signal the
  77.  *                        LDEF to draw only the button, but not the list content.
  78.  *    kDrawIntermediate    The user is expanding/collapsing the folder. Draw
  79.  *                        the animation triangle.
  80.  *    kSelectedElement    This element was selected in the display list. This is
  81.  *                        a temporary value needed when the list is expanded or
  82.  *                        contracted.
  83.  *    kEraseButtonArea    If we are only hiliting the button (while the user has
  84.  *                        pressed the mouse in the button area), we don't need to
  85.  *                        erase the button before redrawing it. When the user clicks
  86.  *                        -- releases the mouse in the button -- the button shape
  87.  *                        will change, so the old shape must be erased. This is
  88.  *                        controlled by this flag.
  89.  * kUserFlagMask        These flags may be used by the calling program.
  90.  */
  91. #define kHasTwistDown        0x0001                /* This element has a sub-list    */
  92. #define    kShowSublist        0x0002                /* Display the sub-list content    */
  93. #define    kOldShowSublist        0x0004                /* Save kShowSublist state        */
  94. #define    kSelectedElement    0x0008                /* Copy "selected" from List    */
  95. #define    kDrawButtonFilled    0x0010                /* Signal "mouseDown" in button    */
  96. #define    kOnlyRedrawButton    0x0020                /* Signal "tracking mouse"        */
  97. #define kDrawIntermediate    0x0040                /* Draw the animation polygon    */
  98. #define    kEraseButtonArea    0x0080                /* Need complete button redraw    */
  99. #define kUserFlagMask        0xFF00                /* Reserved for caller's use    */
  100. #define kFirstUserFlag        0x0100                /* User flags start here        */
  101. #define kUserFlagShift        8                    /* Shift to first user flag bit    */
  102.  
  103. struct TwistDownRecord {
  104.     struct TwistDownRecord    **nextElement;        /* CDR - next on this "level"    */
  105.     struct TwistDownRecord    **subElement;        /* CAR - first in a sublist        */
  106.     short                indentLevel;            /* Indentation depth            */
  107.     unsigned short        flag;                    /* TwistDownFlags                */
  108.     unsigned short        dataLength;                /* Length of actual datum        */
  109.     unsigned char        data[1];                /* Datum to display                */
  110. };
  111. typedef struct TwistDownRecord    TwistDownRecord, *TwistDownPtr, **TwistDownHdl;
  112.  
  113. /*
  114.  * TwistDownSiblingSet simplifies creation of a linked list of TwistDown elements.
  115.  * Usage:
  116.  *        NewTwistDownSiblingSet(&mySiblingSet);
  117.  *        status = MakeTwistDownSibling(&mySiblingSet, ...);
  118.  *        currentElement = mySiblingSet.thisElement;
  119.  *        (**currentElement).subElement = EnumerateChildOfCurrentElement(...);
  120.  *        return (mySiblingSet.firstElement);
  121.  */
  122. struct TwistDownSiblingSet {
  123.     TwistDownHdl        thisElement;            /* This was just created        */
  124.     TwistDownHdl        firstElement;            /* First in this sequence        */
  125.     TwistDownHdl        previousElement;        /* Previous element linkage        */
  126. };
  127. typedef struct TwistDownSiblingSet TwistDownSiblingSet, *TwistDownSiblingSetPtr;
  128.  
  129. /*
  130.  * This is the function that is called to draw the user-specified list cell
  131.  * contents. The port and font have been properly initialized and the viewRect
  132.  * takes indentation into consideration. If this parameter is specified as NULL,
  133.  * DrawText will be used. Note that the application can use the list's refCon to
  134.  * pass other data to the drawing procedure.
  135.  *
  136.  * This function will be called to draw list cells on the display and, if the
  137.  * default print page procedure is provided, to print list element information.
  138.  *
  139.  * Note: this is an incompatible change from the original release of the TwistDown
  140.  * library that makes it possible for the drawing procedure to access the user-
  141.  * controlled flag bits and (though it should not be necessary) the indent level.
  142.  */
  143. typedef pascal void            (*TwistDownDrawProc)(
  144.         ListHandle                twistDownListHdl,    /* The list itself            */
  145.         TwistDownPtr            twistDownPtr,        /* Locked data handle        */
  146.         const Rect                *viewRect            /* Draw in this area        */
  147.     );
  148.  
  149. /*
  150.  * Create a twist-down list. Before calling, you must set the port to the current
  151.  * window and specify the font and font size that is to be used to draw the list.
  152.  * NewTwistDownList creates an empty one-column list with a vertical scroll bar
  153.  * and no grow box. Only one item may be selected at a time; but this could
  154.  * be changed by the application without difficulty.
  155.  *
  156.  * Note: unlike LNew, you should specify a correct viewRect: the scroll bars and
  157.  * frame will be created inside the view rect.
  158.  *
  159.  * The TwistDownDrawProc will be called to draw a selection. If specified as
  160.  * NULL, DrawText will be called.
  161.  *
  162.  * The tabIndent parameter should be set to the amount to indent successive levels
  163.  * (zero means no indentation). Setting it to the widMax value from the current
  164.  * font seems reasonable.
  165.  *
  166.  * canHiliteSelection should be TRUE for normal selection (the selection is
  167.  * hilited). It should be FALSE if you want to supress selection. Because
  168.  * hirearchical lists often "select" by revealing a sub-topic, this may be
  169.  * more reasonable in many cases.
  170.  *
  171.  * isLeftJustify should be set TRUE for systems using the Roman alphabet. It would
  172.  * be set FALSE for right-to-left languages such as Arabic and Hebrew. It is used
  173.  * to configure the direction of the buttons and the location of text within
  174.  * the displayed list cell.
  175.  */
  176. pascal ListHandle            NewTwistDownList(
  177.         const Rect                *viewRect,
  178.         TwistDownDrawProc        drawProc,
  179.         unsigned short            tabIndent,
  180.         Boolean                    canHiliteSelection,
  181.         Boolean                    isLeftJustify,
  182.         Boolean                    hasGrowBox
  183.     );
  184. /*
  185.  * Dispose of a Twist Down List and its private storage. The application program
  186.  * must itself dispose of the list data. theList may be NULL.
  187.  */
  188. pascal void                    DisposeTwistDownList(
  189.         ListHandle                theList
  190.     );
  191.  
  192. /*
  193.  * Move the list within the window.
  194.  */
  195. pascal void                    MoveTwistDownList(
  196.         ListHandle                theList,
  197.         short                    leftEdge,
  198.         short                    topEdge
  199.     );
  200. /*
  201.  * Resize the list. The width and height parameters do not include the horizontal
  202.  * and vertical scrollbars.
  203.  */
  204. pascal void                    SizeTwistDownList(
  205.         ListHandle                theList,
  206.         short                    newWidth,
  207.         short                    newHeight
  208.     );
  209. /*
  210.  * CreateTwistDownButtons is called, internally, when the list is created.
  211.  * if the application program changes the list cell height (by calling LSize),
  212.  * or changes the direction of text it must re-call CreateTwistDownButtons
  213.  * to re-create the twist-down buttons.
  214.  */
  215. pascal void                    CreateTwistDownButtons(
  216.         ListHandle                theList
  217.     );
  218. /*
  219.  * DoTwistDownClick handles all processing after a click in the list window.
  220.  * It returns an indication of the user action:
  221.  *    kTwistDownNotInList
  222.  *        The click was not in this list. Your application may ignore this click or
  223.  *        take other appropriate action.
  224.  *    kTwistDownNoClick
  225.  *        The user released the mouse outside of the list area: this click should be
  226.  *        ignored.
  227.  *    kTwistDownButtonClick
  228.  *        The user clicked on the twist-down button. Expand or contract the list as
  229.  *        appropriate.
  230.  *    kTwistDownClick
  231.  *        The user clicked (once) on a list datum. The application should treat this
  232.  *        as an item selection (or, it may be a click in the scroll bar). This is
  233.  *        the result of a FALSE return from LClick.
  234.  *    kTwistDownDoubleClick
  235.  *        The user double-clicked on a list datum. The application should open this
  236.  *        item or take other appropriate action. This is the result of a TRUE
  237.  *        return from LClick.
  238.  *
  239.  * If DoTwistDownClick returns kTwistDownButtonClick, kTwistDownClick, or
  240.  * kTwistDownDoubleClick, selectedListCell will be set to the cell that the user
  241.  * clicked on.
  242.  */
  243. pascal TwistDownClickState    DoTwistDownClick(
  244.         ListHandle                theList,
  245.         const EventRecord        *eventRecordPtr,
  246.         Cell                    *selectedListCell
  247.     );
  248. /*
  249.  * ExpandOrCollapseTwistdownSubList is called when the user clicks on the
  250.  * twist-down button. index and selectedListCell are the values returned by
  251.  * DoTwistDownClick.
  252.  */
  253. pascal void                    ExpandOrCollapseTwistDownList(
  254.         ListHandle                theList,
  255.         Cell                    selectedListCell
  256.     );
  257. /*
  258.  * SetTwistDownListFont changes the font and font size. It then calls
  259.  * CreateTwistDownButtons to change the twist down button dimensions.
  260.  * SetTwistDownListFont will cause the list to be redrawn, but it does not
  261.  * examine or modify the TwistDown list elements.
  262.  */
  263. pascal void                    SetTwistDownListFont(
  264.         ListHandle                theList,
  265.         short                    fontNumber,
  266.         short                    fontSize
  267.     );
  268. /*
  269.  * Explicitly update a list without waiting for an update event. This would
  270.  * normally only be called after an Alert or Modal Dialog terminates.
  271.  */
  272. pascal void                    UpdateTwistDownList(
  273.         ListHandle                theList
  274.     );
  275.  
  276. /*
  277.  * CreateVisibleList is called when the list is created. It stores the list
  278.  * head into cell [0, 0] and calls BuildVisibleList to instantiate the display.
  279.  */
  280. pascal void                    CreateVisibleList(
  281.         ListHandle                theList,
  282.         TwistDownHdl            twistDownHdl
  283.     );
  284. /*
  285.  * BuildVisibleList is called when the list is created, or when the user clicks on
  286.  * a twist-down button. selectedRow is the first row that needs to be redrawn. The
  287.  * head of the entire list has been stored into cell [0, 0].
  288.  */
  289. pascal void                    BuildVisibleList(
  290.         ListHandle                theList,
  291.         short                    selectedRow
  292.     );
  293. /*
  294.  * GetTwistDownElementHandle returns the TwistDownHdl that is stored in a List
  295.  * cell. It will return NULL if the cell is out of bounds.
  296.  */
  297. pascal TwistDownHdl            GetTwistDownElementHandle(
  298.         ListHandle                theList,
  299.         Cell                    theCell
  300.     );
  301. /*
  302.  * NewTwistDownSiblingSet initializes the variables that will be used to manage
  303.  * a linked list of TwistDown list elements. Together with MakeSibling, it simplifies
  304.  * management of the list.
  305.  */
  306. pascal void                    NewTwistDownSiblingSet(
  307.         TwistDownSiblingSetPtr    twistDownSiblingSetPtr
  308.     );
  309. /*
  310.  * MakeTwistDownSibling adds a new element (by calling MakeTwistDownElement) to
  311.  * the end of the current linked list. It handles the bookkeeping needed for
  312.  * the first element.
  313.  */
  314. pascal OSErr                MakeTwistDownSibling(
  315.         TwistDownSiblingSetPtr    twistDownSiblingSetPtr,
  316.         short                    indentLevel,
  317.         unsigned short            dataLength,
  318.         const Ptr                dataPtr
  319.     );
  320. /*
  321.  * MakeTwistDownElement adds an element to a linked list. It is designed to create
  322.  * elements in a hierarchical linked-list where each element may be followed by a
  323.  * successor (on the same "level") and/or by a child list (on a lower "level").
  324.  * The parameters are as follows:
  325.  *    previousElement
  326.  *        This has a handle to the predecessor to this element. PreviousElement
  327.  *        should be NULL if this is the first element.
  328.  *    indentLevel
  329.  *        This is the indentation-level of this list element. It is only used to tab
  330.  *        the list elements on the visual display. If you never want tabbing, set
  331.  *        tabIndent to zero when the list was created. Indents start at zero.
  332.  *    dataLength
  333.  *        This is the length of the list element datum.
  334.  *    dataPtr
  335.  *        This is a pointer to the first byte of the list element datum. If NULL,
  336.  *        a data block of the requisite size will be created, but the caller is
  337.  *        responsible for filling it in.
  338.  *    result
  339.  *        If MakeElement succeeds, result will will contain a handle to the
  340.  *        list element it created. This is needed to create a successor
  341.  *        element.
  342.  */
  343. pascal OSErr                MakeTwistDownElement(
  344.         TwistDownHdl            previousElement,
  345.         short                    indentLevel,
  346.         unsigned short            dataLength,
  347.         const Ptr                dataPtr,
  348.         TwistDownHdl            *result
  349.     );
  350.  
  351. /*
  352.  * Append the second list to the first. Return the first element.
  353.  */
  354. pascal TwistDownHdl            AppendTwistDownList(
  355.         TwistDownHdl            dstTwistDownHandle,
  356.         TwistDownHdl            srcTwistDownHdl
  357.     );
  358.  
  359. /*
  360.  * This recursive function disposes of the argument list that has the argument
  361.  * at its head, and of all sublists linked to this list. If userProc is non-NULL,
  362.  * it will be called when disposing each handle. This allows the caller to
  363.  * store handle or pointer data within a list element.
  364.  */
  365. typedef pascal void            (*DisposeTwistDownCallback)(
  366.         TwistDownHdl            twistDownHdl,
  367.         void                    *userData
  368.     );
  369.         
  370. pascal void                    DisposeTwistDownHdl(
  371.         TwistDownHdl            twistDownHdl,
  372.         DisposeTwistDownCallback userProc,
  373.         void                    *userData
  374.     );
  375.  
  376. /*
  377.  * Count the number of elements in the list (whether visible or not).
  378.  */
  379. pascal unsigned long        CountListElements(
  380.         TwistDownHdl            twistDownHdl
  381.     );
  382.  
  383. /*
  384.  * Sort a TwistDown list. This sorts the current list, but does not examine any
  385.  * sublists. The caller must provide a comparison function.
  386.  *
  387.  * To sort a list, call SortTwistDownList(&theList, compareFunc, refCon). The
  388.  * sort is not recursive, and returns an error if the function cannot obtain
  389.  * enough scratch storage ((number of elements + 1) * sizeof (Handle))
  390.  */
  391. /*
  392.  * Compare two list elements, returning -1, 0, +1 depending on whether
  393.  * listElementA is less, equal to, or greater than listElementB.
  394.  */
  395. typedef pascal short        (*TwistDownSortCompareProc)(
  396.         void                    *refCon,
  397.         const TwistDownHdl        listElementA,
  398.         const TwistDownHdl        listElementB
  399.     );
  400. /*
  401.  * Sort a list according to the comparison function.
  402.  */
  403. pascal OSErr                SortTwistDownList(
  404.         TwistDownHdl            *twistDownHdlPtr,
  405.         TwistDownSortCompareProc twistDownSortCompareProc,
  406.         void                    *refCon
  407.     );
  408.  
  409. /*
  410.  * Print a TwistDown list. This is a print manager that calls user-provided
  411.  * functions to handle the actual printing process. (Default procedures are
  412.  * provided for text-only lists.) Parameters:
  413.  *        theList                    The ListHandle that contains this list.
  414.  *        printHandlePtr            This is the address of a PrintHandle. If the
  415.  *                                PrintHandle is NULL, a new handle will be
  416.  *                                allocated.
  417.  *        doStyleDialog            TRUE to always display the style dialog.
  418.  *        twistDownPrintSetupProc    This is called once to determine the number
  419.  *                                of pages in the printout. It should set
  420.  *                                (**hPrint).prJob.iLstPage to the total number
  421.  *                                of pages. See the default routine for details.
  422.  *                                If NULL, a default routine will be used that
  423.  *                                prints a simple heading (date, time, and page
  424.  *                                number), then uses the list font information
  425.  *                                to determine the number of pages.
  426.  *        twistDownPrintImageProc    This is called for each page to draw the data.
  427.  *                                If NULL, a default routine will be used that
  428.  *                                works with the setup function. This will use
  429.  *                                the cell display routine that was provided
  430.  *                                to the list creation function.
  431.  *        twistDownPrintExitProc    This is called when printing completes.
  432.  *        clientData                For the caller's use.
  433.  * The caller should call InitCursor (or whatever is appropriate) after
  434.  * PrintTwistDownList exits -- the cursor will be set to the watchCursor.
  435.  */
  436. typedef pascal OSErr (*TwistDownPrintSetupProc)(
  437.         ListHandle                theList,
  438.         THPrint                    printHandle,
  439.         void                    *clientData,
  440.         StringPtr                dateString
  441.     );
  442. typedef pascal OSErr (*TwistDownPrintImageProc)(
  443.         ListHandle                theList,
  444.         THPrint                    printHandle,
  445.         void                    *clientData,
  446.         StringPtr                dateString,
  447.         const Rect                *pageRect,
  448.         short                    pageNumber
  449.     );
  450. typedef pascal OSErr (*TwistDownPrintExitProc) (
  451.         ListHandle                theList,
  452.         void                    *clientData,
  453.         OSErr                    finalStatus
  454.     );
  455. pascal OSErr                PrintTwistDownList(
  456.         ListHandle                theList,
  457.         THPrint                    *printHandlePtr,
  458.         Boolean                    doStyleDialog,
  459.         TwistDownPrintSetupProc    twistDownPrintSetupProc,
  460.         TwistDownPrintImageProc    twistDownPrintImageProc,
  461.         TwistDownPrintExitProc    twistDownPrintExitProc,
  462.         void                    *clientData
  463.     );
  464.  
  465. #endif    /* REZ                */
  466. #endif    /* _TwistDownList_    */
  467.